package com.acme.bankapp.service.bank;

import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.bank.account.Account;
import com.acme.bankapp.domain.bank.client.Client;

import java.util.*;

/**
 * This class gets statistic about bank object
 *
 * @author Alexander Kotov (kotov.alex.22@gmail.com)
 */
public class BankReport {
    private final Bank bank;

    public BankReport(Bank bank) {
        this.bank = bank;
    }

    /**
     * @return counts of bank's clients
     */
    public int getNbOfCustomers() {
        return bank.getClients().size();
    }

    /**
     * @return total counts of bank client's accounts
     */
    public int getNbOfAccounts() {
        int accountsNumber = 0;

        for (Client client : bank.getClients()) {
            accountsNumber += client.getAccounts().size();
        }
        return accountsNumber;
    }

    /*
     * @return list of all bank client's accounts ordered by balance
     */
    public List<Account> getAccountsSortedBySum() {
        List<Account> list = new ArrayList<>();

        for (Client client : bank.getClients()) {
            for (Account account : client.getAccounts()) {
                list.add(account);
            }
        }

        Collections.sort(list, new Comparator<Account>() {
            public int compare(Account a1, Account a2) {
                double balanceDiff = a1.getBalance() - a2.getBalance();
                if (balanceDiff > 0.) {
                    return 1;
                } else if (balanceDiff < 0.) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
        return list;
    }

    /**
     * @return total credit of checking accounts
     */
    public double getBankCredit() {
        double result = 0.;

        for (Client client : bank.getClients()) {
            for (Account account : client.getAccounts()) {
                result -= Math.min(0., account.getBalance());
            }
        }
        return result;
    }

    /**
     * @return map: client -> list of accounts
     */
    public Map<Client, Set<Account>> getCustomerAccount() {
        Map<Client, Set<Account>> map = new HashMap<>();

        for (Client client : bank.getClients()) {
            Set<Account> set = new HashSet<>();
            for (Account account: client.getAccounts()) {
                set.add(account);
            }
            map.put(client, set);
        }
        return map;
    }
}
